package com.easytouch.vmhdl.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.bpit.facepay.FacePayCallback;
import com.baidu.bpit.facepay.FacePayCancelCallback;
import com.baidu.bpit.facepay.FacePayHelper;
import com.baidu.bpit.facepay.LocalErrCode;
import com.baidu.bpit.facepay.OrderInfo;
import com.baidu.idl.face.platform.FaceStatusEnum;
import com.baidu.idl.face.platform.utils.APIUtils;
import com.baidu.idl.face.platform.utils.CameraPreviewUtils;
import com.easytouch.core.utils.Log;
import com.easytouch.core.utils.Tools;
import com.easytouch.vmhdl.R;
import com.easytouch.vmhdl.fragment.PayFragment;
import com.easytouch.vmhdl.utils.FaceSDKResSettings;
import com.easytouch.vmhdl.view.RingView;

import java.text.DecimalFormat;

/**
 * Created by Administrator on 2018/2/28.
 */

public class BaiduFacePayActivity extends Activity implements View.OnClickListener,
        Camera.ErrorCallback,
        Camera.PreviewCallback,
        SurfaceHolder.Callback {

    private static final int RESULT_SHOW_TIME = 4000;

    private FacePayHelper mFacePayHelper;

    private SurfaceView mSurfaceView;

    private Log mLogger = new Log("PayDialog.txt");

    // 识别中View
    private LinearLayout mDetectingLayout;
    private TextView mAmountView;
//    private ScanView mScanView;
    private RingView mRingView;
    private TextView mTipsView;
    private Button mBtnCancel;

    private View detectViewTopBottom;
    private View detectViewLeftRight;

    // 支付中View
    private LinearLayout mPayingLayout;
    private ImageView mPayingImgView;

    private LinearLayout paySuccessNameAmountLayout;
    private LinearLayout paySuccessNameLayout;
    private TextView payStatusIngTextview;
    private TextView payStatusSuccessTextview;
    private TextView payStatusFailTextview;
    private TextView payMessageFailTextview;
    private TextView mSuccessNameTextView;
    private TextView mSuccessAmountTextView;

    private SurfaceHolder mSurfaceHolder;

    // 相机
    private Camera mCamera;
    private Camera.Parameters mCameraParam;
    private int mCameraId;
    private int mPreviewWidth;
    private int mPreviewHeight;
    private int mPreviewDegree;

    private DecimalFormat decimalFormat;

    // 状态标识
    protected boolean mIsCreateSurface = false;

    // 显示Size
    private Rect mPreviewRect = new Rect();
    private Rect mDetectRect = new Rect();
    private int mDisplayWidth = 0;
    private int mDisplayHeight = 0;

    private int goodsPrice;
    private String goodsOrder;
    private String goodsName;
    private int goodsBuyAmount;

    private Handler mHandler = new Handler();
    private Runnable closeRunnable = new Runnable() {
        @Override
        public void run() {
            finish();
        }
    };
    private Animation mStatusInAnimation;
    private Animation mStatusOutAnimation;
    private Animation mMessageInAnimation;
    private String passId;

    private String unitAmount;
    private String unitCount;
    private String totalAmount;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_face_pay);

        Intent intent = getIntent();
        goodsPrice = intent.getIntExtra("goodsPrice", 0);
        goodsName = intent.getStringExtra("goodsName");
        goodsOrder = intent.getStringExtra("order");
        goodsBuyAmount = intent.getIntExtra("buyAmount", 0);
        String newPrice = Tools.priceFormat(String.valueOf(goodsPrice /** mBuyAmount*/));
        unitAmount = newPrice.replace(".", "");
        unitCount = String.valueOf(goodsBuyAmount);
        totalAmount = String.valueOf(Long.valueOf(String.valueOf(this.goodsPrice * Integer.parseInt(unitCount) + Integer.parseInt("0"))));
        mLogger.i("newPrice:" + newPrice + ",unitAmount:" + unitAmount + ",unitCount:" + unitCount + ",totalAmount:" + totalAmount);

        FaceSDKResSettings.initializeResId();

        mFacePayHelper = new FacePayHelper(BaiduFacePayActivity.this);
        initView();

        mFacePayHelper.setDetectSoundEnable(true);

        final OrderInfo orderInfo = new OrderInfo();
        orderIdConfig(orderInfo);

        decimalFormat = new DecimalFormat("0.00");

        if (orderInfo.totalAmount >= 0) {
            mAmountView.setText("待支付金额: "
                    + decimalFormat.format(orderInfo.totalAmount * 1.0d / 100) + "元");
        }

        mFacePayHelper.pay(orderInfo, new FacePayCallback() {
            @Override
            public void onFaceDetectTips(FaceStatusEnum status, String message) {
                mTipsView.setText(message);
            }

            @Override
            public void onPaying() {
                mPayingImgView.setBackgroundResource(R.drawable.paying_state);
                mLogger.i("onPaying");
                mBtnCancel.setVisibility(View.GONE);
                mDetectingLayout.setVisibility(View.GONE);
                mRingView.setVisibility(View.GONE);
                mPayingLayout.setVisibility(View.VISIBLE);
                payStatusIngTextview.setVisibility(View.VISIBLE);
//                mPayingAnimation.start();
                setRotateAnimation(mPayingImgView);
            }

            @Override
            public void onPaySuccess(String name) {
                mPayingImgView.clearAnimation();
                mPayingImgView.setBackgroundResource(R.drawable.pay_success);
                mBtnCancel.setVisibility(View.GONE);
                Intent intent = new Intent(PayFragment.BAIDU_FACE_PAY_SUCCESS);
                sendBroadcast(intent);

                mHandler.postDelayed(closeRunnable, RESULT_SHOW_TIME);

                if (TextUtils.isEmpty(name)) {
                    paySuccessNameLayout.setVisibility(View.GONE);
                } else {
                    paySuccessNameLayout.setVisibility(View.VISIBLE);
                    mSuccessNameTextView.setText(name);
                }

                if (orderInfo.totalAmount >= 0) {
                    mSuccessAmountTextView.setText(decimalFormat.format(orderInfo.totalAmount * 1.0d / 100));
                } else {
                    mSuccessAmountTextView.setText("0");
                }

                paySuccessNameAmountLayout.setVisibility(View.VISIBLE);
                paySuccessNameAmountLayout.startAnimation(mMessageInAnimation);
                payStatusIngTextview.startAnimation(mStatusOutAnimation);
                payStatusSuccessTextview.setVisibility(View.VISIBLE);
                payStatusSuccessTextview.startAnimation(mStatusInAnimation);

                mDetectingLayout.setVisibility(View.GONE);
                mRingView.setVisibility(View.GONE);
                mPayingLayout.setVisibility(View.VISIBLE);
            }

            @Override
            public void onPayError(String errCode, String title, String message) {
                mLogger.i("onPayError," + errCode + "," + title + "," + message);
                mPayingImgView.clearAnimation();
                mPayingImgView.setBackgroundResource(R.drawable.pay_failed);
                mBtnCancel.setVisibility(View.GONE);
                Intent intent = new Intent(PayFragment.BAIDU_FACE_PAY_FAIL);
                sendBroadcast(intent);
                mHandler.postDelayed(closeRunnable, RESULT_SHOW_TIME);

                payStatusFailTextview.setText(title);
                payMessageFailTextview.setText(message);

                payStatusIngTextview.startAnimation(mStatusOutAnimation);
                payStatusFailTextview.setVisibility(View.VISIBLE);
                payStatusFailTextview.startAnimation(mStatusInAnimation);
                payMessageFailTextview.setVisibility(View.VISIBLE);
                payMessageFailTextview.startAnimation(mMessageInAnimation);

                mDetectingLayout.setVisibility(View.GONE);
                mRingView.setVisibility(View.GONE);
                mPayingLayout.setVisibility(View.VISIBLE);
            }
        });
    }

    public void setRotateAnimation(ImageView iv) {
        RotateAnimation rotate = new RotateAnimation(0, 360,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        rotate.setFillAfter(true);
        rotate.setDuration(1000);
        rotate.setRepeatCount(-1);
        iv.startAnimation(rotate);
    }

    private void initView() {
        mSurfaceView = (SurfaceView) findViewById(R.id.port_surface_view);
        mDetectingLayout = (LinearLayout) findViewById(R.id.detecting_layout);

//        mScanView = (ScanView) findViewById(R.id.scan_view);
        mRingView = (RingView) findViewById(R.id.ring_view);
       /* DisplayMetrics dm = new DisplayMetrics();
        Display display = getWindowManager().getDefaultDisplay();
        display.getMetrics(dm);
        mDisplayWidth = dm.widthPixels;
        mDisplayHeight = dm.heightPixels;

        ImageView layoutDetectingBg = findViewById(R.id.layout_detecting_bg);
        layoutDetectingBg.setImageBitmap(
        decodeSampledBitmapFromResource(getResources(), R.drawable.bg_detecting_new, mDisplayWidth,  mDisplayHeight));*/

        mTipsView = (TextView) findViewById(R.id.port_tips);
        mAmountView = (TextView) findViewById(R.id.amount_taxtview);
        detectViewTopBottom = findViewById(R.id.layout_detect_top_bottom);
        detectViewLeftRight = findViewById(R.id.layout_detect_left_right);
        mBtnCancel = findViewById(R.id.port_close);
        mBtnCancel.setOnClickListener(this);
        mPayingLayout = (LinearLayout) findViewById(R.id.paying_layout);
        mPayingImgView = findViewById(R.id.img_status_paying);

        payStatusIngTextview = findViewById(R.id.pay_status_ing_textview);
        payStatusSuccessTextview = findViewById(R.id.pay_status_success_textview);
        payStatusFailTextview = findViewById(R.id.pay_status_fail_textview);
        payMessageFailTextview = findViewById(R.id.pay_fail_message_layout);
        paySuccessNameAmountLayout = findViewById(R.id.pay_success_name_amount_layout);
        paySuccessNameLayout = findViewById(R.id.pay_success_name_layout);
        mMessageInAnimation = AnimationUtils.loadAnimation(BaiduFacePayActivity.this, R.anim.anim_message_in);
        mStatusOutAnimation = AnimationUtils.loadAnimation(BaiduFacePayActivity.this, R.anim.anim_status_out);
        mStatusInAnimation = AnimationUtils.loadAnimation(BaiduFacePayActivity.this, R.anim.anim_status_in);

        mSuccessNameTextView = (TextView) findViewById(R.id.success_name_textview);
        mSuccessAmountTextView = (TextView) findViewById(R.id.success_amount_textview);

        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.setSizeFromLayout();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // 源图片的高度和宽度
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            // 计算出实际宽高和目标宽高的比率
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            // 选择宽和高中最小的比率作为inSampleSize的值，这样可以保证最终图片的宽和高一定都会大于等于目标的宽和高。
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
        // 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }


    private void orderIdConfig(OrderInfo orderInfo) {
        orderInfo.accessKey = "fengguo_facepay_online"; //测试环境 test 正式环境  ak sk fengguo_facepay_online
        orderInfo.serverSignTime = 1511160254;
        orderInfo.serverNonce = 2089;
        orderInfo.serverSign = "3eede6d900c8697b8d173268b9612db3";//正式环境 3eede6d900c8697b8d173268b9612db3  测试环境f7efb30a166b3c42ea6e4c4db5c62f19
        orderInfo.passId = passId;
        orderInfo.merchantId = 2; //正式环境 2,测试环境 6
        orderInfo.orderCreateTime = 1511160043000L;
        orderInfo.orderId = goodsOrder;
        orderInfo.goodsName = goodsName;
        orderInfo.goodsDesc = "fg";
        orderInfo.goodsUrl = "http://cp01-rdqa-dev340-wangying31.epc.baidu.com:8080/pay/notify/facebpit";
        orderInfo.unitAmount = TextUtils.isEmpty(unitAmount) ? 0 : Long.valueOf(/*unitAmount*/"1");
        orderInfo.unitCount = TextUtils.isEmpty(unitCount) ? 0 : Long.valueOf(unitCount);
        orderInfo.transportAmount = 0;
        mLogger.i("tatalAmount 01:" + totalAmount);
        orderInfo.totalAmount = /*TextUtils.isEmpty(totalAmount) ? 0 : Long.valueOf(totalAmount)*/Long.valueOf("1");
        mLogger.i("orderInfo.totalAmount:" + orderInfo.totalAmount);
        orderInfo.pageUrl = "http://db-testing-eb07.db01.baidu.com:8666/success.html";
        orderInfo.returnUrl = "http://cp01-rdqa-dev340-wangying31.epc.baidu.com:8080/pay/notify/facebpit";
        orderInfo.buyerSpUsername = "buyer_sp_username";
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        mIsCreateSurface = true;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (holder.getSurface() == null) {
            return;
        }

        new Handler().postDelayed(new Runnable() {
            public void run() {
                startPreview();
            }
        }, 500);

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        mIsCreateSurface = false;
    }

    protected void startPreview() {
        if (mSurfaceView != null && mSurfaceView.getHolder() != null) {
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(this);
        }

        if (mCamera == null)
            mCamera = open();

        try {
            if (mCameraParam == null) {
                mCameraParam = mCamera.getParameters();
            }
        } catch (RuntimeException e) {
            mLogger.i("未检测到摄像头设备，请稍后重试，cause:" + e.getCause());
            Toast.makeText(BaiduFacePayActivity.this, "未检测到摄像头设备，请稍后重试", Toast.LENGTH_SHORT).show();
            return;
        }

//        mCameraParam.setPictureFormat(PixelFormat.JPEG);
        int degree = displayOrientation(BaiduFacePayActivity.this);

        mCamera.setDisplayOrientation(degree);
        // 设置后无效，camera.setDisplayOrientation方法有效
        mCameraParam.set("rotation", degree);

//        mPreviewDegree = degree == 0 ? 360 : degree;
        mPreviewDegree = degree;

        Point point = CameraPreviewUtils.getBestPreview(mCameraParam, new Point(mSurfaceView.getWidth(), mSurfaceView.getHeight()));

        mPreviewWidth = point.x;
        mPreviewHeight = point.y;

        mLogger.i("mPreviewWidth:" + mPreviewWidth + ",mPreviewHeight:" + mPreviewHeight);

        float ratioX;
        float ratioY;

        mPreviewRect.set(0, 0, mPreviewHeight, mPreviewWidth);

        if (degree == 90 || degree == 270) {
            ratioX = (mPreviewHeight * 1f) / (mSurfaceView.getWidth() * 1f);
            ratioY = (mPreviewWidth * 1f) / (mSurfaceView.getHeight() * 1f);
        } else {
            ratioX = (mPreviewWidth * 1f) / (mSurfaceView.getWidth() * 1f);
            ratioY = (mPreviewHeight * 1f) / (mSurfaceView.getHeight() * 1f);
        }

        mDetectRect = new Rect(
                (int) (detectViewLeftRight.getLeft() * ratioX),
                (int) (detectViewTopBottom.getTop() * ratioY),
                (int) (detectViewLeftRight.getRight() * ratioX),
                (int) (detectViewTopBottom.getBottom() * ratioY));

        mCameraParam.setPreviewSize(mPreviewWidth, mPreviewHeight);
        mCamera.setParameters(mCameraParam);

        mFacePayHelper.setDetectConfig(mPreviewDegree, mPreviewRect, mDetectRect);

        mLogger.i("_________________________________________________________");
        mLogger.i("mPreviewDegree:" + mPreviewDegree);
        mLogger.i("mPreviewRect:" + mPreviewRect.left + ", "
                + mPreviewRect.top + ", "
                + mPreviewRect.right + ", "
                + mPreviewRect.bottom + ", ");
        mLogger.i("mDetectRect:" + mDetectRect.left + ", "
                + mDetectRect.top + ", "
                + mDetectRect.right + ", "
                + mDetectRect.bottom + ", ");
        mLogger.i("_________________________________________________________");

        try {
            mCamera.setPreviewDisplay(mSurfaceHolder);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            mCamera.stopPreview();
            mCamera.setErrorCallback(this);
            mCamera.setPreviewCallback(this);
        } catch (Exception e) {
            try {
                mCamera.release();
            } catch (RuntimeException e2) {
                e2.printStackTrace();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            mCamera = null;
        }
        mCamera.startPreview();
    }

    private Camera open() {
        Camera camera;
        int numCameras = Camera.getNumberOfCameras();
        if (numCameras == 0) {
            return null;
        }

        int index = 0;
        while (index < numCameras) {
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(index, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                break;
            }
            index++;
        }

        if (index < numCameras) {
            camera = Camera.open(index);
            mCameraId = index;
        } else {
            camera = Camera.open(0);
            mCameraId = 0;
        }
        return camera;
    }

    private int displayOrientation(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        int rotation = windowManager.getDefaultDisplay().getRotation();
        int degrees = 0;
        if (rotation == Surface.ROTATION_0) {
            degrees = 0;

        } else if (rotation == Surface.ROTATION_90) {
            degrees = 90;

        } else if (rotation == Surface.ROTATION_180) {
            degrees = 180;

        } else if (rotation == Surface.ROTATION_270) {
            degrees = 270;

        } else {
            degrees = 0;

        }
        int result = (0 - degrees + 360) % 360;
        if (APIUtils.hasGingerbread()) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(mCameraId, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                result = (info.orientation + degrees) % 360;
                result = (360 - result) % 360;
            } else {
                result = (info.orientation - degrees + 360) % 360;
            }
        }
        return result;
    }

    @Override
    public void onError(int i, Camera camera) {
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        mFacePayHelper.setDetectConfig(mPreviewDegree, mPreviewRect, mDetectRect);
        mFacePayHelper.detectData(data);
    }

    protected void stopPreview() {
        if (mCamera != null) {
            try {
                mCamera.setErrorCallback(null);
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    mCamera.release();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
                mCamera = null;
            }
        }
        if (mSurfaceHolder != null) {
            mSurfaceHolder.removeCallback(this);
        }
    }

  /*  @Override
    protected void onResume() {
        super.onResume();
        startPreview();
    }*/

    @Override
    protected void onStop() {
        super.onStop();
        stopPreview();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopPreview();
    }

    /*  @Override
    public void dismiss() {
        super.finish();
        destroy();

    }*/

    @Override
    public void finish() {
        super.finish();
        destroy();
    }

    protected void destroy() {
        if (mCamera != null) {
            try {
                mCamera.setErrorCallback(null);
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    mCamera.release();
                } catch (RuntimeException e2) {
                    e2.printStackTrace();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                mCamera = null;
            }
        }
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        switch (id) {
            case R.id.port_close:
                stopPreview();
                mFacePayHelper.cancle(new FacePayCancelCallback() {
                    @Override
                    public void onCancelSuccess() {
                        finish();
                        Toast.makeText(BaiduFacePayActivity.this, "取消订单成功", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onCancelFail(int errCode) {
                        if (errCode == LocalErrCode.CANCEL_PAYING) {
                            Toast.makeText(BaiduFacePayActivity.this, "取消订单失败，请等待支付结果", Toast.LENGTH_SHORT).show();
                        } else if (errCode == LocalErrCode.CANCEL_COMPLETED) {
                            Toast.makeText(BaiduFacePayActivity.this, "订单取消失败，订单已完成", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
                break;
        }
    }
}
